<template>
  <view
    :id="fabId"
    class="doc-fab tn-cool-bg-7"
    :style="fabStyle"
    @touchstart.stop.prevent="handleTouchStart"
    @touchmove.stop.prevent="handleTouchMove"
    @touchend.stop.prevent="handleTouchEnd"
  >
    <view class="icon tn-flex-center">
      <tn-icon icon="level"></tn-icon>
    </view>

    <view class="arc__wrap">
      <view
        v-for="item in 6"
        :key="item"
        class="arc__item">
        <view class="arc__content"></view>
      </view>
    </view>
  </view>
</template>

<script lang="ts" setup>
import {
  computed,
  CSSProperties,
  reactive,
  watch,
  getCurrentInstance,
  ComponentInternalInstance,
onMounted,
nextTick
} from 'vue'
import TnIcon from '@/tuniao-ui/components/tn-icon/src/Icon.vue'
import { handleValueWithUnit, getRectInfo, uuid } from '@/tuniao-ui/utils'
import useSystemInfo from '@/tuniao-ui/libs/hooks/useSystemInfo'

type PointValue = {
  x: number,
  y: number
}

// props
type Props = {
  /** 按钮类型 */
  type?: 'button' | 'nav',
  /** 距离顶部的距离, 单位rpx */
  top?: number,
  /** 距离左边的距离, 单位rpx */
  left?: number,
  /** zIndex */
  zIndex?: string | number
}
const props = withDefaults(defineProps<Props>(), {
  type: 'button',
  zIndex: 9999
})

// emits
type Emits = {
  (e: 'click'): void
}
const emits = defineEmits<Emits>()

// fab的样式
const fabStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}
  if (touchPosition.y) style.top = handleValueWithUnit(touchPosition.y, 'px')
  if (touchPosition.x) style.left = handleValueWithUnit(touchPosition.x, 'px')
  if (props?.zIndex !== undefined) style.zIndex = Number(props.zIndex)
  return style
})

const { updateSystemInfo, systemInfo, customNavbar } = useSystemInfo()
updateSystemInfo()

const instance = getCurrentInstance() as ComponentInternalInstance
let touchPosition = reactive<PointValue>({
  x: 0,
  y: 0
})
let startTouchOldPosition: PointValue = {
  x: 0,
  y: 0
}
watch(() => {
  return [props.left, props.top]
}, (val) => {
  touchPosition.x = val[0] || 0
  touchPosition.y = val[1] || 0
},{
  immediate: true
})
// 获取fabRect信息
let fabId: string = uuid()
let initCount: number = 0
let fabWidth: number = 0
const getFabRectInfo = async () => {
  const rect = await getRectInfo(`#${fabId}`, instance)
  if (!rect) {
    if (initCount > 10) {
      console.error('[doc-fab]初始化fab失败, 获取位置信息失败')
      return
    }
    setTimeout(() => {
      getFabRectInfo()
      initCount++
    }, 50);
    return
  }

  initCount = 0

  touchPosition.x = rect.left || 0
  // #ifdef H5
  touchPosition.y = (rect.top || 0) + customNavbar.value.height
  // #endif
  // #ifndef H5
  touchPosition.y = (rect.top || 0)
  // #endif
  fabWidth = rect.width || 0
}

// 处理触摸事件
let touchStartTime: number = 0
let moving: boolean = false
const minValue: number = 10
const touchStartPoint: PointValue = {
  x: 0,
  y: 0
}
const handleTouchStart = (e: TouchEvent) => {
  const touches = e.touches
  // 禁止多指触控
  if (touches?.length > 1) return
  moving = true
  touchStartPoint.x = touches[0].clientX
  touchStartPoint.y = touches[0].clientY
  startTouchOldPosition.x = touchPosition.x
  startTouchOldPosition.y = touchPosition.y
  touchStartTime = new Date().getTime()
}
const handleTouchMove = (e: TouchEvent) => {
  const touches = e.touches
  // 禁止多指触控
  if (touches?.length > 1 || !moving) return
  const touchPoint = touches[0]
  let x: number = startTouchOldPosition.x + (touchPoint.clientX - touchStartPoint.x)
  let y: number = startTouchOldPosition.y + (touchPoint.clientY - touchStartPoint.y)

  // 边缘判断
  const xMaxValue = systemInfo.value.safeAreaWidth - minValue - fabWidth
  const yMaxValue = systemInfo.value.screenHeight - customNavbar.value.height - minValue
  if (x < minValue) {
    x = minValue
  } else if (x > xMaxValue) {
    x = xMaxValue
  }
  if (y < minValue + customNavbar.value.height) {
    y = minValue + customNavbar.value.height
  } else if (y > yMaxValue) {
    y = yMaxValue
  }
  // console.log(x, y);
  touchPosition.x = x
  touchPosition.y = y
}
const handleTouchEnd = (e: TouchEvent) => {
  const touches = e.touches
  // 禁止多指触控
  if (touches?.length > 1 || !moving) return

  // 判断时候为点击
  const currentTime = new Date().getTime()
  if (currentTime - touchStartTime < 200) {
    handleFabClick()
    return
  }

  moving = false
}

// fab点击事件
const handleFabClick = () => {
  emits('click')
}

onMounted(() => {
  nextTick(() => {
    setTimeout(() => {
      getFabRectInfo()
    }, 50);
  })
})
</script>

<style lang="scss" scoped>

.doc-fab {
  position: fixed;
  bottom: 10%;
  right: 4%;
  width: 100rpx;
  height: 100rpx;
  border-radius: 50%;
  animation: suspension 1.5s ease-in-out infinite alternate;

  &:after {
    content: " ";
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    border-radius: inherit;
    background-image: url(./lib/images/icon_bg6.png);
    background-size: 100% 100%;
  }

  .icon {
    width: 100%;
    height: 100%;
    font-size: 60rpx;
    font-weight: 500;
    line-height: 1;
  }
}

.arc {
  &__wrap {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    transform: rotateY(75deg) rotateZ(10deg) rotateX(0deg);
    animation: arcWrapRotate 20s linear infinite;
  }
  &__item {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    @for $i from 1 through 6 {
      &:nth-child(#{$i}) {
        transform: scale(1.3) rotateX(45deg * $i) rotateZ(45deg * $i);
      }
    }
  }
  &__content {
    width: 100%;
    height: 100%;
    background-image: url(./lib/images/arc3.png);
    background-size: 100% 100%;
    transform-origin: center center;
    animation: arcRotate 4s linear infinite;
  }
}

@keyframes suspension {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(-0.8rem);
  }
}
@keyframes arcWrapRotate {
  from {
    transform: rotateY(75deg) rotateZ(10deg) rotateX(0deg);
  }
  to {
    transform: rotateY(75deg) rotateZ(10deg) rotateX(-360deg);
  }
}
@keyframes arcRotate {
  to {
    transform: rotate(360deg);
  }
}
</style>
